//=======================================================
//AUTHOR: JEFF XL. ZHANG ARIZONA STATE UNIVERSITY
//ALL RIGHTS RESERVED  2008
//=======================================================
#pragma once
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include "line.h"
#include "detection.h"
#include "display.h"
#include "line_feature.h"
#include "line_feature_detection.h"
#include "image_feature.h"
#include "data_structure.h"
#include "feature_comparison.h"
#include "line_database.h"
#include "test_histogram.h"

using namespace std;

bool SHOW = 0;	
bool DEBUG = 0;	
bool PRINT_TO_FILE = 1;	
bool DEBUG_HIST = 0;	
bool HV_CLASSIFICATION = 0;

void extraction_process(vector<Line> lines, IplImage *img, ImageFeature& aframe){

	aframe.set_image(img);
	aframe.set_lines(lines);
	LineFeatureDetector alinefeaturedetector;
	Histogram hist;

	//TESTING MODULE ==========================================================================================
//	test_hist_visualization();
//	test_hist_comparison(frame_anchor,frame_target);
	//TEST ENDED HERE==========================================================================================
	
	
	//	for(int i = 0; i < 1; i++){		//FOR TESTING PURPOSE
	for(int i = 0; i < lines.size(); i++){		//FOR EACH LINE
		alinefeaturedetector.extract_line_featrue(img,lines[i],5);
//		alinefeaturedetector.verticalness?Num_V++:Num_H++;
		aframe.NUM_V += (int)alinefeaturedetector.verticalness;
		aframe.NUM_H += 1-(int)alinefeaturedetector.verticalness;
//		cout<<alinefeaturedetector.verticalness<<endl;
		
	//HISTOGRAM
		hist = alinefeaturedetector.compute_profile_histogram_array(img,lines[i],10,0);
	//TURNED OFF FOR DEBUGGING HIST_VISUALIZATION
		hist.visualize(1,1,i);	// 5,3 MOJO NUMBER

		aframe.Hists.push_back(hist);
	}
	if(HV_CLASSIFICATION) cout<<"Horizonta Lines: "<<aframe.NUM_H<<"	Vertical Lines: "<<aframe.NUM_V<<endl;
}


void scheme_complete_iterating(void){
char filename_target[300],filename_anchor[300];
	char directory[300] = "C:/Documents and Settings/Jeff/My Documents/Data/Robot/Cubic_Nov/CLIP_20081104-222809/";
//	char directory[300] = "C:/Documents and Settings/Jeff/My Documents/Data/Robot/Cubic_Nov/CLIP_20081104-224210/";
	
	int offset = DEBUG?5:10;
	int loop_for_frames = DEBUG?1:100;
	int time_interval = DEBUG?0:50;
	int increment = DEBUG?1:5;
	int start_point = 1597;		//GOOD:1597		//for2809 1650
	int debug_point_anchor = 1192;		//GOOD:1597		//for2809 1192
	int debug_point_target = 1190;		//GOOD:1597		//for2809 1190
	LineDatabase linedb;

	vector<Line> lines_anchor, lines_target;
	Detection adetection;
	LineFeature afeature;
	ImageFeature aframe;
	FeatureComparison acomparison;

	for(int i = 0; i < loop_for_frames; i++){		//N
	//	char filename_anchor[300] = "C:/Documents and Settings/Jeff/My Documents/My Pictures/QuickCam/Picture 22.jpg";
	//	char filename_target[300] = "C:/Documents and Settings/Jeff/My Documents/My Pictures/QuickCam/Picture 23.jpg";
		sprintf(filename_target,"%sframe%d.jpg",directory,start_point +i*increment);
		sprintf(filename_anchor,"%sframe%d.jpg",directory,start_point +i*increment+offset);

		if(DEBUG){
			sprintf(filename_target,"%sframe%d.jpg",directory,debug_point_anchor);
			sprintf(filename_anchor,"%sframe%d.jpg",directory,debug_point_target);
		}
		IplImage *img_anchor = cvLoadImage(filename_anchor,1);
		IplImage *img_target = cvLoadImage(filename_target,1);
		Display("anchor",img_anchor);	
		Display("target",img_target);	

		//Detection
		lines_anchor = adetection.DetectLine(img_anchor,"anchor");
		lines_target = adetection.DetectLine(img_target,"target");

		if(lines_anchor.empty() || lines_target.empty()) continue;
		ImageFeature frame_anchor, frame_target;


	//	extraction_process(lines,img,aframe);
		extraction_process(lines_anchor,img_anchor,frame_anchor);
		extraction_process(lines_target,img_target,frame_target);
		
		
	//	Display("demo_anchor",frame_anchor.get_image());
		acomparison.compare(frame_anchor,frame_target);		//INPUT TWO FRAMES 


	//TESTING MODULE ==========================================================================================
		if (DEBUG_HIST){
			test_hist_visualization();
			test_hist_comparison();
		}
	//TEST ENDED HERE==========================================================================================

//		linedb.set_lines_for_frame(lines);

		cvReleaseImage(&img_anchor);
		cvReleaseImage(&img_target);

		cvWaitKey(time_interval);
	}
}

void scheme_zig_zag(void){
	char filename_target[300],filename_anchor[300];
	char directory[300] = "C:/Documents and Settings/Jeff/My Documents/Data/Robot/Cubic_Nov/CLIP_20081104-222809/";
//	char directory[300] = "C:/Documents and Settings/Jeff/My Documents/Data/Robot/Cubic_Nov/CLIP_20081104-224210/";
	int offset = DEBUG?50:10;
	int time_interval = DEBUG?50:0;
	double VERTICAL_THRESHOLD = 6;
	int increment = 5;
	int loop_for_frames = DEBUG?5*increment:20*increment;
	int start_point = 839;		//GOOD:1597		//for2809 1650
	int debug_point_anchor = 1192;		//GOOD:1597		//for2809 1192
	int debug_point_target = 1190;		//GOOD:1597		//for2809 1190
	fstream file_output, file_output_h, file_output_v;
	char savename[300], savename_h[300], savename_v[300];
	sprintf(savename,"output/l_c_%d_%d.txt",start_point,start_point+loop_for_frames*increment+offset);
	sprintf(savename_h,"output/l_c_%d_%d_h.txt",start_point,start_point+loop_for_frames*increment+offset);
	sprintf(savename_v,"output/l_c_%d_%d_v.txt",start_point,start_point+loop_for_frames*increment+offset);
	file_output.open(savename,fstream::out|fstream::app);
	file_output_h.open(savename_h,fstream::out|fstream::app);
	file_output_v.open(savename_v,fstream::out|fstream::app);

	vector<Line> lines_anchor, lines_target;
	Detection adetection;
	FeatureComparison acomparison;
	LineFeature afeature;
//	ImageFeature frame_anchor, frame_target;
	vector<LineElem> line_elements_universal;
	int target_line_index_buffer;

	for(int i = 0; i < loop_for_frames/increment; i++)
	{		//N
		cout<<"==========================================Segment "<<i*increment<<"====================="<<endl;
		ImageFeature frame_target;
		sprintf(filename_target,"%sframe%d.jpg",directory,start_point +i*increment);
		IplImage *img_target = cvLoadImage(filename_target,1);
		Display("target",img_target);	
		lines_target = adetection.DetectLine(img_target,"target");
		extraction_process(lines_target,img_target,frame_target);

		//PUSH LINES IN target INTO LINEELEMENT VECTOR -------- 1 frame
		for (int j = 0; j < lines_target.size(); j++)
		{
			LineElem line_elem_buffer(i*increment,j,lines_target[j]);
			cout<<"LENGTH = "<< line_elem_buffer.length<<endl;
			line_elements_universal.push_back(line_elem_buffer);			
			line_elem_buffer.print();

			if(PRINT_TO_FILE){
				char *output_buffer; //[line_elem_buffer.length];
				output_buffer = new char[line_elem_buffer.length];
				line_elem_buffer.get_as_string(output_buffer);
//				file_output.write(output_buffer,line_elem_buffer.length);	file_output<<"\n";
				if(line_elem_buffer.get_slope()> VERTICAL_THRESHOLD){
					file_output_v.write(output_buffer,line_elem_buffer.length);	file_output_v<<"\n";
				}
				else{
					file_output_h.write(output_buffer,line_elem_buffer.length);	file_output_h<<"\n";
				}
				delete output_buffer;
			}
		}

		for (int j = i*increment + 1; j < (i + 1)*increment; j++)  // 1 - M(increment)	----------M frames
		{
			cout<<"-----------------------------------------Frame "<<j<<"----------------------"<<endl;
			ImageFeature frame_anchor;
			sprintf(filename_anchor,"%sframe%d.jpg",directory,start_point + i*increment + j + 1);		
			IplImage *img_anchor = cvLoadImage(filename_anchor,1);
 			Display("anchor",img_anchor);	

			//Detection
			lines_anchor = adetection.DetectLine(img_anchor,"anchor");
			if(lines_anchor.empty() || lines_target.empty()) continue;
			extraction_process(lines_anchor,img_anchor,frame_anchor);
		
		//	Display("demo_anchor",frame_anchor.get_image());
			acomparison.compare(frame_anchor,frame_target);		//INPUT TWO FRAMES 
			int new_line_id = lines_target.size();

			for (int k = 0; k < lines_anchor.size(); k++)	//FOR EVERY LINE IN ANCHOR		-------- 1 frame  1 line
			{
				//FIND WHICH LINE in anchor DOES j MATCHED WITH
				target_line_index_buffer = -1;	//UNLESS MATCH WAS FOUND, THIS VALUE WILL REMAIN NEGATIVE
				for (int m = 0; m < acomparison.mutual_match.size(); m++)		// ENUMERATE MUTUAL_MATCH
				{
					if (acomparison.mutual_match[m].get_index1() == k){
						target_line_index_buffer = acomparison.mutual_match[m].get_index2(); //PROVIDE CORRESPONDING TARGET LINE INDEX: 
						break;
					}
				}
				//CONSTRUCT line_elements_buffer
				if(target_line_index_buffer >= 0) {
					LineElem line_elem_buffer(j,target_line_index_buffer,lines_anchor[k]);
					//INSERT INTO line_elements_universal
					line_elements_universal.push_back(line_elem_buffer);			
					line_elem_buffer.print();
					char *output_buffer; //[line_elem_buffer.length];
					output_buffer = new char[line_elem_buffer.length];
					line_elem_buffer.get_as_string(output_buffer);
//					file_output.write(output_buffer,line_elem_buffer.length);	file_output<<"\n";
					if(line_elem_buffer.get_slope()>VERTICAL_THRESHOLD){
						file_output_v.write(output_buffer,line_elem_buffer.length);	file_output_v<<"\n";
					}
					else{
						file_output_h.write(output_buffer,line_elem_buffer.length);	file_output_h<<"\n";
					}
					delete output_buffer;
				}
/*				else{
					new_line_id++;
					LineElem line_elem_buffer(j,new_line_id,lines_anchor[k]);
					//INSERT INTO line_elements_universal
					line_elements_universal.push_back(line_elem_buffer);			
					line_elem_buffer.print();
				}
*/			}
//			cvWaitKey(time_interval);
			acomparison.mutual_match.clear();
 			cvReleaseImage(&img_anchor);
		}
//		cvWaitKey(time_interval);
		cvReleaseImage(&img_target);
	}

	file_output.close();
}


void test_line_elem(void){
	int frame_id = 4;
	int line_id[] = {0,2,5,7,11};
	Line aline(cvPoint(3.5,2.1),cvPoint(5.1,2.0));
	LineElem alineelem(frame_id,line_id[2],aline);
	alineelem.print();
//	char *print = alineelem.print();
//	cout<< print <<endl;
	cin.get();
}

void main(void){
	
//	scheme_complete_iterating();
	scheme_zig_zag();
//	test_line_elem();
}	
